package com.whf.android.jar.base.delegate;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;

import com.blankj.utilcode.util.GsonUtils;
import com.blankj.utilcode.util.KeyboardUtils;
import com.blankj.utilcode.util.ObjectUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.lxj.xpopup.XPopup;
import com.lxj.xpopup.impl.LoadingPopupView;
import com.whf.android.jar.app.Latte;
import com.whf.android.jar.base.oi.IOutListener;
import com.whf.android.jar.net.HttpCode;
import com.whf.android.jar.net.callback.IError;
import com.whf.android.jar.net.callback.IFailure;
import com.whf.android.jar.net.callback.ISuccess;
import com.whf.android.jar.net.utils.RestClientUtils;

import java.util.List;
import java.util.WeakHashMap;

import me.yokeyword.fragmentation.anim.DefaultHorizontalAnimator;
import me.yokeyword.fragmentation.anim.FragmentAnimator;

/**
 * 界面
 *
 * @author qf
 * @version 2020-03-23
 */
public abstract class BaseDelegate extends AbstractDelegate implements IPageLoadListener,
        IFailure, IError, ISuccess {

    private LoadingPopupView loadingPopup = null;
    private IOutListener outListener;

    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);

        //这里是类型转换，而不是判断
        if (context instanceof IOutListener) {
            outListener = (IOutListener) context;
        }
    }

    @Override
    public void onLazyInitView(@Nullable Bundle savedInstanceState) {
        super.onLazyInitView(savedInstanceState);
        if (setMourning()) {
            setMourning(mRootView);
        }
    }

    /**
     * 是否配置该界面为灰白界面
     */
    protected boolean setMourning() {
        return false;
    }

    /**
     * @param view:灰白界面
     */
    protected void setMourning(View view) {
        if (Latte.getMourning() && view != null) {
            Paint paint = new Paint();
            ColorMatrix cm = new ColorMatrix();
            cm.setSaturation(0);//灰度效果
            paint.setColorFilter(new ColorMatrixColorFilter(cm));
            view.setLayerType(View.LAYER_TYPE_HARDWARE, paint);
        }
    }

    @SuppressWarnings("unchecked")
    public <T extends BaseDelegate> T getParentDelegate() {
        return (T) getParentFragment();
    }

    @Override
    public FragmentAnimator onCreateFragmentAnimator() {
        return new DefaultHorizontalAnimator();
    }

    @Deprecated
    public void setLoading(String loading) {
        showLoading(loading);
    }

    @Deprecated
    public void showLoadingDialog() {
        showLoading();
    }

    @Deprecated
    public void hideLoadingDialog() {
        hideLoading();
    }

    @Override
    public void showLoading() {
        showLoading("正在加载中");
    }

    @Override
    public void showLoading(String loading) {
        showLoading(loading, false);
    }

    @Override
    public void showLoading(String loading, boolean showLoading) {
        if (loadingPopup == null) {
            loadingPopup = (LoadingPopupView) new XPopup.Builder(Latte.getActivity())
                    .dismissOnTouchOutside(showLoading)
                    .dismissOnBackPressed(showLoading)
                    .hasBlurBg(hasBlurBg())//是否设置背景为高斯模糊背景。默认为false
                    .asLoading(loading)
                    .show();
        } else {
            loadingPopup.setTitle(loading).show();
        }
    }

    /**
     * 加载进度条是否设置背景为高斯模糊背景。默认为false
     */
    protected boolean hasBlurBg() {
        return false;
    }

    @Override
    public void hideLoading() {
        if (null != loadingPopup) {
            loadingPopup.dismiss();
        }
    }

    @Override
    public void inGet(String url, ISuccess success) {
        RestClientUtils.create(this, this).inGet(url, success);
    }

    @Override
    public void inGet(String url, String ids, ISuccess success) {
        RestClientUtils.create(this, this).inGet(url, ids, success);
    }

    @Override
    public void inGet(String url, WeakHashMap<String, Object> params, ISuccess success) {
        RestClientUtils.create(this, this).inGet(url, params, success);
    }

    @Override
    public void upSubmit(String url, Object data) {
        if (data instanceof String) {
            inPost(url, (String) data, this);
        } else {
            inPost(url, GsonUtils.toJson(data), this);
        }
    }

    @Override
    public void inPart(String url, WeakHashMap<String, Object> params, ISuccess success) {
        RestClientUtils.create(this, this).inPart(url, params, success);
    }

    @Override
    public void inPost(String url, WeakHashMap<String, Object> params, ISuccess success) {
        RestClientUtils.create(this, this).inPost(url, params, success);
    }

    @Override
    public void inPost(String url, String data, ISuccess success) {
        RestClientUtils.create(this, this).inPost(url, data, success);
    }

    @Override
    public void inPost(String url, ISuccess success) {
        RestClientUtils.create(this, this).inPost(url, success);
    }

    @Override
    public void upPut(String url, Object data) {
        if (data instanceof String) {
            inPut(url, (String) data, this);
        } else {
            inPut(url, GsonUtils.toJson(data), this);
        }
    }

    @Override
    public void inPut(String url, String data, ISuccess success) {
        RestClientUtils.create(this, this).inPut(url, data, success);
    }

    @Override
    public void responseSubmit() {
        getSupportDelegate().setFragmentResult(Activity.RESULT_OK, null);
        getSupportDelegate().pop();
    }

    @Override
    public void upPath(String url, List<String> result) {
        RestClientUtils.create(this, this)
                .inPath(url, result, new ISuccess() {
                    @Override
                    public void onSuccess(String response) {
                        onSuccessPath(response);
                    }
                });
    }

    @Override
    public void inPath(String url, List<String> result, ISuccess success) {
        RestClientUtils.create(this, this)
                .inPath(url, result, success);
    }

    @Override
    public void inPath(String url, String data, ISuccess success) {
        RestClientUtils.create(this, this)
                .inPath(url, data, success);
    }

    @Override
    public void download(String url, String name, ISuccess success) {
        RestClientUtils.create(this, this)
                .download(url, name, success);
    }

    @Override
    public void onFailure() {
        hideLoading();
        ToastUtils.showShort("连接服务器失败，请稍后再试。");
    }

    @Override
    public void onSuccess(String response) {
        hideLoading();
        responseSubmit();
    }

    @Override
    public void onError(int code, String msg) {
        hideLoading();
        if (Latte.getSignExpiration() == code) {
            ToastUtils.showShort("登录超时");
            outSignIn();
        } else if (HttpCode.CODE_404 == code) {
            ToastUtils.showShort("服务器找不到请求的接口");
        } else if (HttpCode.CODE_500 == code && Latte.getServerError()) {
            ToastUtils.showShort("服务器遇到错误，无法完成请求");
        } else if (HttpCode.CODE_501 == code && Latte.getServerError()) {
            ToastUtils.showShort("服务器无法识别请求方法");
        } else if (HttpCode.CODE_502 == code && Latte.getServerError()) {
            ToastUtils.showShort("服务器网关或代理错误，无法完成请求");
        } else if (HttpCode.CODE_503 == code && Latte.getServerError()) {
            ToastUtils.showShort("服务器目前无法使用");
        } else if (HttpCode.CODE_504 == code && Latte.getServerError()) {
            ToastUtils.showShort("服务器网关或代理超时，无法完成请求");
        } else if (HttpCode.CODE_505 == code && Latte.getServerError()) {
            ToastUtils.showShort("服务器不支持请求中所用的 HTTP 协议版本");
        } else if (ObjectUtils.isEmpty(msg)) {
            ToastUtils.showShort("服务器异常，请联系管理员");
        } else {
            ToastUtils.showShort(msg);
        }
    }

    @Override
    public void outSignIn() {
        if (outListener != null) {
            outListener.outSignIn();
        }
    }

    @Override
    public void onSuccessPath(String response) {

    }

    /****************************************** 操作成功，回调 ************************************/

    public final void closeWeb() {
        goodPop(Activity.RESULT_OK, null);
    }

    protected final void goodPop() {
        goodPop(Activity.RESULT_OK, null);
    }

    /**
     * @param bundle:返回参数
     */
    protected final void goodPop(Bundle bundle) {
        goodPop(Activity.RESULT_OK, bundle);
    }

    /**
     * @param resultCode:返回代码
     * @param bundle:返回参数
     */
    protected final void goodPop(int resultCode, Bundle bundle) {
        KeyboardUtils.hideSoftInput(Latte.getActivity());
        getSupportDelegate().setFragmentResult(resultCode, bundle);
        getSupportDelegate().pop();
    }

    /****************************************** 跳转 ********************************************/

    private long startTime = 0;

    /**
     * @param delegate：跳转
     */
    protected void start(BaseDelegate delegate) {
        if (System.currentTimeMillis() - startTime > 666) {
            startTime = System.currentTimeMillis();
            if (delegate == null) {
                return;
            }
            BaseDelegate oneDelegate = getParentDelegate();
            if (oneDelegate != null) {
                BaseDelegate twoDelegate = oneDelegate.getParentDelegate();
                if (twoDelegate != null) {
                    BaseDelegate threeDelegate = twoDelegate.getParentDelegate();
                    if (threeDelegate != null) {
                        threeDelegate.getSupportDelegate().start(delegate);
                    } else {
                        twoDelegate.getSupportDelegate().start(delegate);
                    }
                } else {
                    oneDelegate.getSupportDelegate().start(delegate);
                }
            } else {
                getSupportDelegate().start(delegate);
            }
        }
    }

    /**
     * @param delegate:跳转,返回可以刷新界面
     * @param requestCode:跳转,返回可以刷新界面
     */
    protected void startForResult(BaseDelegate delegate, int requestCode) {
        if (System.currentTimeMillis() - startTime > 666) {
            startTime = System.currentTimeMillis();
            if (delegate == null) {
                return;
            }
            BaseDelegate oneDelegate = getParentDelegate();
            if (oneDelegate != null) {
                BaseDelegate twoDelegate = oneDelegate.getParentDelegate();
                if (twoDelegate != null) {
                    BaseDelegate threeDelegate = twoDelegate.getParentDelegate();
                    if (threeDelegate != null) {
                        threeDelegate.getSupportDelegate().startForResult(delegate, requestCode);
                    } else {
                        twoDelegate.getSupportDelegate().startForResult(delegate, requestCode);
                    }
                } else {
                    oneDelegate.getSupportDelegate().startForResult(delegate, requestCode);
                }
            } else {
                getSupportDelegate().startForResult(delegate, requestCode);
            }
        }
    }

    /**
     * 拨打电话（跳转到拨号界面，用户手动点击拨打）
     *
     * @param phoneNum 电话号码
     */
    public final void callPhone(String phoneNum) {
        final Intent intent = new Intent(Intent.ACTION_DIAL);
        final Uri data = Uri.parse("tel:" + phoneNum);
        intent.setData(data);
        ContextCompat.startActivity(context, intent, null);
    }

    /**
     * 发短信
     *
     * @param uri：跳转到发短信界面
     */
    protected final void callShortLetter(String uri) {
        //打电话
        final Intent intent = new Intent(Intent.ACTION_SENDTO);
        final Uri data = Uri.parse(uri);
        intent.setData(data);
        ContextCompat.startActivity(context, intent, null);
    }

    /**
     * 发短信
     *
     * @param phone：跳转到发短信界面
     * @param body：短信内容
     */
    public final void callShortLetter(String phone, String body) {
        //发短信
        final String sms = "sms";
        final Uri data = Uri.parse(sms + "to:" + phone);
        final Intent intent = new Intent(Intent.ACTION_SENDTO, data);
        intent.putExtra(sms + "_body", body);
        ContextCompat.startActivity(context, intent, null);
    }

    /**
     * 发邮件
     *
     * @param email:接收人
     * @param emailCC:抄送人
     * @param subject:主题
     * @param text:正文
     */
    protected final void callMail(String[] email,
                                  String[] emailCC,
                                  String subject,
                                  String text) {
        //发邮件
        final Intent intent = new Intent(Intent.ACTION_SEND);
        intent.setType("message/rfc822"); // 设置邮件格式
        intent.putExtra(Intent.EXTRA_EMAIL, email); // 接收人
        intent.putExtra(Intent.EXTRA_CC, emailCC); // 抄送人
        intent.putExtra(Intent.EXTRA_SUBJECT, subject); // 主题
        intent.putExtra(Intent.EXTRA_TEXT, text); // 正文
        ContextCompat.startActivity(context, Intent.createChooser(intent, "请选择邮件类应用"), null);
    }

}
